﻿//-----------------------------------------------------------------------
// <copyright file="CustomTokenValidation.cs" company="HCL">
//     Copyright (c) HCL Technologies.  All rights reserved.
// </copyright>
// <summary>
// Class for the user authentication validation
// </summary>
//-----------------------------------------------------------------------
namespace HCLT.Practice.WindowsAzure.Solution.STSAuthentication
{
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.DirectoryServices;
    using System.Runtime.InteropServices;

    /// <summary>
    /// This class will validate the user credential on the network and 
    /// retrieve the user information from the local network active directory
    /// </summary>
    public class CustomTokenValidation
    {
        /// <summary>
        /// valid domain name
        /// </summary>
        private string validDomainName;

        /// <summary>
        /// will accepr the active directory claims
        /// </summary>
        private string[] actParam = ConfigInformation.ActiveDirectoryClaimTypes;

        /// <summary>
        /// Initializes a new instance of the CustomTokenValidation class 
        /// and also initialize the domain name with domain name from settings
        /// </summary>
        public CustomTokenValidation()
        {
            this.validDomainName = ConfigurationManager.AppSettings.Get("ValidDomain");
        }

        /// <summary>
        /// This method is exported from active directory dll to validate the user network credential
        /// </summary>
        /// <param name="lpszUsername">network username</param>
        /// <param name="lpszDomain">network domain</param>
        /// <param name="lpszPassword">network password</param>
        /// <param name="logonType">network login type</param>
        /// <param name="logonProvider">network login provider</param>
        /// <param name="token">inptr token this can be blank</param>
        /// <returns>returns true if login is valid else false</returns>
        [DllImport("ADVAPI32.dll", EntryPoint = "LogonUserW", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool LogonUser(
                                    string lpszUsername,
                                    string lpszDomain,
                                    string lpszPassword,
                                    int logonType,
                                    int logonProvider,
                                    ref IntPtr token);

        /// <summary>
        /// method will validate the user identity on the given network
        /// </summary>
        /// <param name="userName">User login name</param>
        /// <param name="password">User login password</param>
        /// <returns>boolen network login status</returns>
        public bool ValidateUserIdentity(string userName, string password)
        {
            IntPtr token = IntPtr.Zero;
            UserInformation userInfo = new UserInformation(userName);
            bool loginValid = LogonUser(userInfo.DomainUserName, userInfo.DomainName, password, 3, 0, ref token);
            return loginValid;

            ////if (!loginValid)
            ////{
            ////    throw new Exception("");
            ////}
        }

        /// <summary>
        /// This method will return the user information from active directory for producing claims
        /// </summary>
        /// <param name="userName">Network user login id</param>
        /// <returns>dictionary with key pair token name values</returns>
        public Dictionary<string, string> GetUserInformationFromActiveDirectory(string userName)
        {
            Dictionary<string, string> propDict = new Dictionary<string, string>();
            UserInformation userInfo = new UserInformation(userName);
            
            ////DirectoryEntry objDirEntry = new DirectoryEntry("LDAP://HCLTECH");
            DirectoryEntry objDirEntry = new DirectoryEntry(userInfo.DomainActiveDirectory);
            DirectorySearcher objActDirSrch = new DirectorySearcher(objDirEntry);
            objActDirSrch.Filter = "(SAMAccountName=" + userInfo.DomainUserName + ")";
            SearchResultCollection objSrchResult = objActDirSrch.FindAll();
            if (objSrchResult.Count > 0)
            {
                foreach (string propInfo in this.actParam)
                {
                    if (objSrchResult[0].Properties[propInfo] != null)
                    {
                        foreach (var propValue in objSrchResult[0].Properties[propInfo])
                        {
                            propDict[propInfo] = propValue.ToString();
                        }
                    }
                }
            }

            return propDict;
        }
    }
}